﻿namespace NServiceBus.AcceptanceTesting;

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Pipeline;
using Transport;

class SubscriptionBehavior<TContext>(
    Action<SubscriptionEvent, TContext> action,
    TContext scenarioContext,
    MessageIntent intentToHandle)
    : IBehavior<ITransportReceiveContext, ITransportReceiveContext>
    where TContext : ScenarioContext
{
    public async Task Invoke(ITransportReceiveContext context, Func<ITransportReceiveContext, Task> next)
    {
        await next(context).ConfigureAwait(false);
        var subscriptionMessageType = GetSubscriptionMessageTypeFrom(context.Message);
        if (subscriptionMessageType != null)
        {
            if (!context.Message.Headers.TryGetValue(Headers.SubscriberTransportAddress, out var returnAddress))
            {
                context.Message.Headers.TryGetValue(Headers.ReplyToAddress, out returnAddress);
            }

            if (!context.Message.Headers.TryGetValue(Headers.SubscriberEndpoint, out var endpointName))
            {
                endpointName = string.Empty;
            }

            var intent = (MessageIntent)Enum.Parse(typeof(MessageIntent), context.Message.Headers[Headers.MessageIntent], true);
            if (intent != intentToHandle)
            {
                return;
            }

            action(new SubscriptionEvent
            {
                MessageType = subscriptionMessageType,
                SubscriberReturnAddress = returnAddress,
                SubscriberEndpoint = endpointName
            }, scenarioContext);
        }
    }

    static string? GetSubscriptionMessageTypeFrom(IncomingMessage msg) => msg.Headers.GetValueOrDefault(Headers.SubscriptionMessageType);
}